package com.umeox.watch.moto.dataservice.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
import android.telephony.NeighboringCellInfo;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.util.Pair;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.AndroidUtils;
import com.umeox.moto.common.utils.NetUtils;
import com.umeox.moto.common.utils.StringUtils;
import com.umeox.watch.location.proto.LocationProto;
import com.umeox.watch.moto.dataservice.BuildConfig;
import com.umeox.watch.moto.dataservice.base.BaseApp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils {

    private static final Pattern REPEAT_EXP = Pattern.compile("[0-1]{7}");

    /**
     * 解析时间段字符串
     *
     * @param timeRange 特别关心时段,24小时制 08:30-20:00
     * @return
     */
    public static String[] parsePeriod(String timeRange) {
        if (StringUtils.isEmpty(timeRange)) {
            return null;
        }
        String[] rtn = new String[4];
        String[] s1 = timeRange.split("-");

        String[] s2 = s1[0].split(":");
        rtn[0] = s2[0];
        rtn[1] = s2[1];

        s2 = s1[1].split(":");
        rtn[2] = s2[0];
        rtn[3] = s2[1];

        return rtn;
    }

    /**
     * 判断时间段，重复周期格式是否正确
     * 正确格式：1100011  7个字节长度，只允许0或者1
     */
    public static boolean isInvalidRepeatExpression(String repeatExpression) {
        return REPEAT_EXP.matcher(repeatExpression).matches();
    }

    /**
     * 判断时间段格式是否正确
     * 正确格式：HH:mm-HH:mm ,24小时制,例：08:30-20:00
     */
    public static boolean isInvalidPeriod(String period) {
        if (StringUtils.isEmpty(period)) {
            return false;
        }
        String rep = "^([01][0-9]|2[0-3]):([0-5][0-9])-([01][0-9]|2[0-3]):([0-5][0-9])$";
        Pattern p = Pattern.compile(rep);
        return p.matcher(period).matches();
    }

    /**
     * 判断服务器闹钟时间格式是否正确 HH:mm
     */
    public static boolean isHHmm(String alarmTimeStr) {
        if (StringUtils.isEmpty(alarmTimeStr)) {
            return false;
        }
        String rexp = "^(([0-1][0-9])|2[0-3]):[0-5][0-9]$";
        Pattern pat = Pattern.compile(rexp);
        Matcher mat = pat.matcher(alarmTimeStr);
        return mat.matches();
    }

    /**
     * 设置手表情景模式为响铃加震动
     */
    public static void ringAndVibrate(Context context) {
        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Settings.System.putInt(context.getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 1);
        }
        Logger.d("设置情景模式：响铃+震动");
    }

    /**
     * 设置手表情景模式为响铃无震动
     */
    public static void ring(Context context) {
        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Settings.System.putInt(context.getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 0);
        }
        Logger.d("设置情景模式：响铃");
    }

    /**
     * 设置手表情景模式为震动
     */
    public static void vibrate(Context context) {
        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audio.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
        Logger.d("设置情景模式：震动");
    }

    /**
     * 判断定位服务是否可用
     */
    public static boolean isLocationEnabled(Context context) {
        int locationMode = 0;
        try {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return false;
        }
        return locationMode != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
    }

    /**
     * 开启位置服务，不然不能定位
     *
     * @param context
     * @return true 表示开启
     */
    public static void setHighAccuracyLocationMode(final Context context) {
        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
        Logger.i("切换定位模式");
    }

    /**
     * 判断 Wifi 是否启用
     *
     * @param context
     * @return
     */
    public static boolean isWifiEnabled(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            int wifiSleepValue = Settings.Global.getInt(context.getContentResolver(),
                    Settings.Global.WIFI_SLEEP_POLICY,
                    Settings.Global.WIFI_SLEEP_POLICY_DEFAULT);
            if (wifiSleepValue != Settings.Global.WIFI_SLEEP_POLICY_NEVER) {
                Settings.Global.putInt(context.getContentResolver(),
                        Settings.Global.WIFI_SLEEP_POLICY,
                        Settings.Global.WIFI_SLEEP_POLICY_NEVER);
            }
        }
        return NetUtils.isWifiEnabled();
    }

    @SuppressLint("MissingPermission")
    public static String getCurrentCellTower(Context context) {
        String mcc, mnc;
        Pair<Integer, Integer> pair = AndroidUtils.getCellInfo();
        mcc = String.valueOf(pair.first);
        mnc = String.valueOf(pair.second);

        //cellId,lac,mcc,mnc,signal
        String format = "%1$s#%2$s#%3$s#%4$s#%5$s";
        String cellTower = null;

        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        CellLocation currentCellInfo = telephonyManager.getCellLocation();
        try {
            int lac = -1, cid = -1;
            // GSM网
            if (currentCellInfo instanceof GsmCellLocation) {
                GsmCellLocation gsm = (GsmCellLocation) currentCellInfo;
                lac = gsm.getLac();
                cid = gsm.getCid();
            }
            // 电信cdma网
            else if (currentCellInfo instanceof CdmaCellLocation) {
                CdmaCellLocation cdma = (CdmaCellLocation) currentCellInfo;
                lac = cdma.getNetworkId();
                cid = cdma.getBaseStationId();
                Logger.e("getCurrentCellTower cid=" + cid + ",lac=" + lac);
            } else {
                Logger.w("CellLocation is null!!!");
            }
            cellTower = String.format(Locale.ENGLISH,
                    format,
                    mcc,
                    mnc,
                    cid,
                    lac,
                    65);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cellTower;
    }

    @SuppressLint("MissingPermission")
    public static List<String> getNearByCellTowers(final Context context) {
        String mcc, mnc;
        Pair<Integer, Integer> pair = AndroidUtils.getCellInfo();
        mcc = String.valueOf(pair.first);
        mnc = String.valueOf(pair.second);

        ArrayList<String> cells = new ArrayList<>();
        String format = "%1$s#%2$s#%3$s#%4$s#%5$s";
        String cellTower = "";

        TelephonyManager tel = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        List<CellInfo> cellInfos = tel.getAllCellInfo();
        Logger.i("所有基站信息->" + cellInfos);
        List<NeighboringCellInfo> neighboringCellInfos = null;//tel.getNeighboringCellInfo();
        Logger.i("附近基站信息->" + neighboringCellInfos);
        if (cellInfos != null && !cellInfos.isEmpty()) {
            for (CellInfo cellInfo : cellInfos) {
                if (cellInfo instanceof CellInfoGsm) {
                    CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            format,
                            mcc,
                            mnc,
                            cellInfoGsm.getCellIdentity().getCid(),
                            cellInfoGsm.getCellIdentity().getLac(),
                            cellInfoGsm.getCellSignalStrength().getDbm());
                } else if (cellInfo instanceof CellInfoCdma) {
                    CellInfoCdma cellInfoCdma = (CellInfoCdma) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            format,
                            mcc,
                            mnc,
                            cellInfoCdma.getCellIdentity().getBasestationId(),
                            cellInfoCdma.getCellIdentity().getNetworkId(),
                            cellInfoCdma.getCellSignalStrength().getDbm());
                } else if (cellInfo instanceof CellInfoLte) {
                    CellInfoLte cellInfoLte = (CellInfoLte) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            format,
                            mcc,
                            mnc,
                            cellInfoLte.getCellIdentity().getCi(),
                            cellInfoLte.getCellIdentity().getTac(),
                            cellInfoLte.getCellSignalStrength().getDbm());
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
                        && cellInfo instanceof CellInfoWcdma) {
                    CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            format,
                            mcc,
                            mnc,
                            cellInfoWcdma.getCellIdentity().getCid(),
                            cellInfoWcdma.getCellIdentity().getLac(),
                            cellInfoWcdma.getCellSignalStrength().getDbm());
                }

                if (!StringUtils.isEmpty(cellTower)) {
                    if (cellInfo.isRegistered() && cells.size() < 7) {
                        cells.add(0, cellTower);
                    } else {
                        if (cells.size() < 7) {
                            cells.add(cellTower);
                        }
                    }
                }
            }
        } else if (neighboringCellInfos != null && !neighboringCellInfos.isEmpty()) {
            for (NeighboringCellInfo cellInfo : neighboringCellInfos) {
                cellTower = String.format(Locale.ENGLISH,
                        format,
                        mcc,
                        mnc,
                        cellInfo.getCid(),
                        cellInfo.getLac(),
                        cellInfo.getRssi());
                if (cells.size() < 7) {
                    cells.add(cellTower);
                }
            }
        }

        return cells;
    }

    public static int getSignalStrengthDbm(SignalStrength signalStrength) {
        int level = -1;
        try {
            Method levelMethod = SignalStrength.class.getDeclaredMethod("getDbm");
            level = (int) levelMethod.invoke(signalStrength);
        } catch (Exception e) {
            Log.e("ClockView", "getSignalStrengthsLevel: ", e);
        }
        return level;
    }

    public static List<LocationProto.WifiPoint> getWifiPoints() {
        WifiManager wifiManager = (WifiManager) BaseApp.getInstance().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiConnection = wifiManager.getConnectionInfo();
        LocationProto.WifiPoint currentWIFI = null;
        if (wifiConnection != null
                && !StringUtils.isEmpty(wifiConnection.getBSSID())
                && !"00:00:00:00:00:00".equalsIgnoreCase(wifiConnection.getBSSID())) {
            String address = wifiConnection.getBSSID();
            String ssid = wifiConnection.getSSID().replace("\"", "");
            String signal = wifiConnection.getRssi() + "";
            currentWIFI = LocationProto.WifiPoint.newBuilder().addWifiPoint(address).addWifiPoint(ssid).addWifiPoint(signal).build();
        }

        List<LocationProto.WifiPoint> wifiInfoList = new ArrayList<>();
        try {
            List<ScanResult> lsScanResult = wifiManager.getScanResults();
            Logger.e("lsScanResult.size:" + lsScanResult.size());
            for (ScanResult result : lsScanResult) {
                if (result.level >= -100
                        && !StringUtils.isEmpty(result.BSSID)
                        && !"00:00:00:00:00:00".equalsIgnoreCase(result.BSSID)
                        && !(currentWIFI != null ? currentWIFI.getWifiPoint(0) : "").equalsIgnoreCase(result.BSSID)
                        && wifiInfoList.size() < 6) {
                    wifiInfoList.add(LocationProto.WifiPoint.newBuilder().addWifiPoint(result.BSSID).addWifiPoint(result.SSID).addWifiPoint(String.valueOf(result.level)).build());
                }
            }

            Collections.sort(wifiInfoList, new Comparator<LocationProto.WifiPoint>() {
                @Override
                public int compare(LocationProto.WifiPoint o1, LocationProto.WifiPoint o2) {
                    int i = Integer.parseInt(o1.getWifiPoint(2));
                    int j = Integer.parseInt(o2.getWifiPoint(2));
                    return i - j;
                }
            });

            if (currentWIFI != null) {
                wifiInfoList.add(0, currentWIFI);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wifiInfoList;
    }


    /**
     * @return
     * @category 判断是否有外网连接（普通方法不能判断外网的网络是否连接，比如连接上局域网）
     */
    public static boolean ping(String... ips) {
        if (!BuildConfig.DEBUG) {
            return false;
        }

        String ip;
        if (ips != null && ips.length > 0) {
            if (StringUtils.isEmpty(ips[0])) {
                ip = "www.baidu.com";
            } else {
                ip = ips[0];
            }
        } else {
            ip = "www.baidu.com";
        }

        String result = null;
        try {
            Process p = Runtime.getRuntime().exec("ping -c 3 -w 5 " + ip);// ping网址3次
            // 读取ping的内容，可以不加
            InputStream input = p.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(input));
            StringBuffer stringBuffer = new StringBuffer("");
            String content = "";
            while ((content = in.readLine()) != null) {
                stringBuffer.append(content);
            }
            Log.i("Ping", "------ping----- result content : " + stringBuffer);
            LogUtils.saveMqttLog("------ping----- result content : " + stringBuffer);
            // ping的状态
            int status = p.waitFor();
            if (status == 0) {
                result = "success";
                return true;
            } else {
                result = "failed";
            }
        } catch (IOException e) {
            result = "IOException";
        } catch (InterruptedException e) {
            result = "InterruptedException";
        } finally {
            Log.i("Ping", "----result---result = " + result);
            LogUtils.saveMqttLog("----result---result = " + result);
        }
        return false;
    }
}
